package com.rslai.commons.validator.jsonvalidator.schema;

import com.alibaba.fastjson.JSONArray;
import com.rslai.commons.validator.jsonvalidator.JsonValidator;
import com.rslai.commons.validator.jsonvalidator.matchers.JsonAssert;
import com.rslai.commons.validator.jsonvalidator.validators.DisorderValidator;
import com.rslai.commons.validator.jsonvalidator.validators.OrderValidator;
import com.rslai.commons.validator.jsonvalidator.validators.Validator;

import java.util.ArrayList;
import java.util.List;

import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;

/**
 * 数组Schema，处理JSON数组的对比
 */
public class ArrayRuleSchema extends Schema<Object> {
    List<Schema<Object>> schemaList;

    /**
     * 构造函数
     */
    public ArrayRuleSchema() {
    }

    /**
     * 构造函数
     * @param schemas schema
     */
    public ArrayRuleSchema(List<Schema<Object>> schemas) {
        schemaList = schemas;
    }

    /**
     * 校验
     * @param parentKey 父key
     * @param object 对象
     */
    @Override
    public void validate(String parentKey, Object object) {
        JsonAssert.assertThat("期望" + parentKey + "是数组类型", object, instanceOf(JSONArray.class));

        JSONArray array = (JSONArray) object;
        if (getSchemaList().size() != 0) {
            String reason = parentKey + "实际得到的数组大小与期望的数组大小不匹配";
            JsonAssert.assertThat(reason, array.size(), is(getSchemaList().size()), getOriginalSchemaStr(), object);
        }
        Validator validator = new DisorderValidator(null);
        if (JsonValidator.arrayDefaultOrderValidate) {
            validator = new OrderValidator(null);
        }
        validator.setCurrentKeyPath(parentKey);
        validator.setValueSchema(this);
        validator.validate(object);
    }

    /**
     * 返回schema字符串
     * @return schema字符串
     */
    @Override
    public String getOriginalSchemaStr() {
        List<Object> result = new ArrayList<Object>();
        for (int index = 0; index < getSchemaList().size(); index++) {
            result.add(getSchemaList().get(index).getOriginalSchemaStr());
        }
        return trimColon(result.toString() + getAttrOriginalStr());
    }

    /**
     * 返回schema list
     * @return list
     */
    public List<Schema<Object>> getSchemaList() {
        if (schemaList == null) {
            schemaList = new ArrayList<Schema<Object>>();
        }
        return schemaList;
    }

    /**
     * 追加schema
     * @param schema schema
     */
    public void addSchema(Schema<Object> schema) {
        getSchemaList().add(schema);
    }

    /**
     * toString方法
     * @return string
     */
    @Override
    public String toString() {
        return "ArrayRuleSchema{attrRule=" + getAttrRule() + ", schemaList=" + schemaList + '}';
    }

}
